package hevs.greencontrol.objects;


import hevs.greencontrol.objects.Room.RoomMode;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;

public class DrawView extends View implements OnTouchListener {

	// DATA
	private List<Room> rooms;
	private Room currentRoom;
	private PlanMode mode;
	private Context context;
	private boolean moveRoom;
	private int cornerToMove;

	// Mode of the plan
	public enum PlanMode {NORMAL, EDIT_SELECT, EDIT_RECTANGLE, EDIT_CUSTOM}

	// METHODS

	/**
	 * Constructor
	 * @param context
	 */
	public DrawView(Context context)
	{
		super(context);

		this.context = context;
		//  setFocusable(true);
		//  setFocusableInTouchMode(true);

		rooms = new ArrayList<Room>();
		
		mode = PlanMode.NORMAL;
		
		moveRoom = false;
		cornerToMove = -1;

		this.setOnTouchListener(this);


		//        paint.setAntiAlias(true);
	}

	/**
	 * Method call to draw the screen
	 */
	@Override
	public void onDraw(Canvas canvas)
	{
		for (Room room : rooms)
		{
			room.drawRoom(canvas);
		}
		
		
		
		
		// set the paint parameters
		 Paint paint = new Paint();
		paint.setColor(Color.WHITE);
		paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(4);
        
		canvas.drawCircle(0,0, 10, paint);
		canvas.drawCircle(0,this.getHeight(), 10, paint);
		canvas.drawCircle(this.getWidth(),0, 10, paint);
		canvas.drawCircle(this.getWidth(),this.getHeight(), 10, paint);
	}

	/**
	 * Method call on touch of the screen
	 */
	@Override
	public boolean onTouch(View view, MotionEvent event)
	{
		Point clickedPoint = new Point(event.getX(), event.getY());
		
		// Normal mode
		if(mode == PlanMode.NORMAL)
		{
			// actions on click
			if (event.getAction() == MotionEvent.ACTION_DOWN)
			{
				Log.i("salut",event.getX() + " " +  event.getY());
				for (Room room : rooms)
				{
					// if clicked in a room, enter the room
					if(room.clickedInRoom(clickedPoint))
					{
						Toast.makeText(context, "Room clicked, go to next screen", Toast.LENGTH_SHORT).show();
					}
				}
			}
		}
		
		// Edit_select mode
		if(mode == PlanMode.EDIT_SELECT)
		{
			// actions on click
			if (event.getAction() == MotionEvent.ACTION_DOWN)
			{
				// if click on a room, switch room mode
				for (Room room : rooms)
				{
					// if mode = normal, switch to edit
					if(room.getMode() == RoomMode.NORMAL)
					{
						// check if clicked in room
						if(room.clickedInRoom(clickedPoint))
						{
							room.switchMode();
							break;
						}
					}
					// if mode = edit and clicked near center, move the room
					else if(room.clickedNearCenter(clickedPoint))
					{
						moveRoom = true;
						room.setOldCenter(clickedPoint);
						currentRoom = room;
						break;
					}
					// if mode = edit and clicked near corner, move the corner
					else if(room.clickedNearCorner(clickedPoint) != -1)
					{
						cornerToMove = room.clickedNearCorner(clickedPoint);
						currentRoom = room;
						break;
					}
					// if mode = edit and no other action, switch to normal
					else
					{
						// check if clicked in room
						if(room.clickedInRoom(clickedPoint))
						{
							room.switchMode();
							break;
						}
					}
				}
				
				invalidate();
			}
			// actions on move
			else if (event.getAction() == MotionEvent.ACTION_MOVE)
			{
				if(moveRoom)
				{
					currentRoom.moveToNewCenter(clickedPoint);
					currentRoom.setOldCenter(clickedPoint);
				}
				else if(cornerToMove != -1)
				{
					currentRoom.moveCorner(cornerToMove, clickedPoint);
				}
				
				invalidate();
			}
			// actions on release
			else if (event.getAction() == MotionEvent.ACTION_UP)
			{
				currentRoom = null;
				moveRoom = false;
				cornerToMove = -1;
				invalidate();
			}
		}		
		
		
		// Edit_rectangle mode
		if(mode == PlanMode.EDIT_RECTANGLE)
		{
			// actions on click
			if (event.getAction() == MotionEvent.ACTION_DOWN)
			{
				// create a new room
				if(currentRoom == null)
				{
					currentRoom = new Room(RoomMode.CONSTRUCT_RECTANGLE);
					
					// set the first point of the rectangle
					currentRoom.setTopLeftRect(clickedPoint);
				}
				else
				{
					// adjust the opposite point of the rectangle on move
					currentRoom.setBottomRightRect(clickedPoint);
					
					// add the room to the list
					if(!rooms.contains(currentRoom))
					{
						rooms.add(currentRoom);
					}
				}
				
				invalidate();
			}
			// actions on move
			else if (event.getAction() == MotionEvent.ACTION_MOVE)
			{
				// adjust the opposite point of the rectangle on move
				currentRoom.setBottomRightRect(clickedPoint);
				
				// add the room to the list
				if(!rooms.contains(currentRoom))
				{
					rooms.add(currentRoom);
				}
				
				invalidate();
			}
			// actions on release
			else if (event.getAction() == MotionEvent.ACTION_UP)
			{
				// if construction finished, set normal mode
				if(currentRoom.getArea() > 2500)
				{
					currentRoom.setMode(RoomMode.NORMAL);
					currentRoom = null;
				}
				
				invalidate();
			}
		}
		
		// Edit_custom mode
		if(mode == PlanMode.EDIT_CUSTOM)
		{
			// actions on click
			if (event.getAction() == MotionEvent.ACTION_DOWN)
			{
				// create a new room
				if(currentRoom == null)
				{
					currentRoom = new Room(RoomMode.CONSTRUCT_CUSTOM);
				}
				
				// add the point in the list
				currentRoom.addPoint(clickedPoint);
				
				// add the room to the list
				if(!rooms.contains(currentRoom))
				{
					rooms.add(currentRoom);
				}
				
				invalidate();
			}
			// actions on move
			else if (event.getAction() == MotionEvent.ACTION_MOVE)
			{
				// adjust the last added point
				currentRoom.adjustLastPoint(clickedPoint);
				
				invalidate();
			}
			// actions on release
			else if (event.getAction() == MotionEvent.ACTION_UP)
			{
				// if construction finished, set normal mode
				if( currentRoom.clickedNearOrigine(clickedPoint) && 
					currentRoom.getNumberPoints() > 1)
				{
					currentRoom.deleteLastPoint();
					
					if(currentRoom.getNumberPoints() > 2)
					{
						currentRoom.setMode(RoomMode.NORMAL);
						currentRoom = null;
					}
				}
				
				invalidate();
			}
		}

		return true;
	}

	/**
	 * Delete selected rooms
	 */
	public void deleteSelectedRooms()
	{
		
		for( Iterator <Room> iterator = rooms.iterator() ; iterator.hasNext();)
		{
			Room room = iterator.next();
			
			if(room.getMode() == RoomMode.EDIT)
			{
				iterator.remove();
			}
		}
		invalidate();
	}
	
	/**
	 * Clean the plan by deleting constructing rooms and setting normal the editing rooms
	 */
	private void cleanPlan()
	{
		for( Iterator <Room> iterator = rooms.iterator() ; iterator.hasNext();)
		{
			Room room = iterator.next();
			
			if(room.getMode() == RoomMode.EDIT)
			{
				room.setMode(RoomMode.NORMAL);
			}
			
			if( room.getMode() == RoomMode.CONSTRUCT_CUSTOM || 
				room.getMode() == RoomMode.CONSTRUCT_RECTANGLE)
			{
				iterator.remove();
			}
		}
		
		currentRoom = null;
	}

	// Getter / Setter
	
	/**
	 * Get the mode of the plan
	 * @return mode
	 */
	public PlanMode getMode()
	{
		return mode;
	}

	/**
	 * Set the mode of the plan
	 * @param mode
	 */
	public void setMode(PlanMode mode)
	{
		cleanPlan();
		this.mode = mode;
		invalidate();
	}
}